package com.qiaofang.applet.service.other.service.impl;

import com.qiaofang.applet.common.base.MongoBaseService;
import com.qiaofang.applet.common.context.QfContextHolder;
import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.service.other.domain.Topic;
import com.qiaofang.applet.service.other.repository.TopicRepository;
import com.qiaofang.applet.service.other.service.TopicService;
import com.qiaofang.applet.service.other.service.dto.TopicDetailDto;
import com.qiaofang.applet.service.other.service.dto.TopicQueryDto;
import com.qiaofang.applet.service.other.service.mapstruct.TopicMapper;
import com.qiaofang.applet.service.property.service.dto.CityQueryDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @description
 * @author luojuan
 * @date 2020/9/12 10:42
 **/
@Slf4j
@Service
public class TopicServiceImpl extends MongoBaseService<Topic, String>  implements TopicService {

    private final TopicRepository topicRepository;

    @Autowired
    private TopicMapper topicMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    public TopicServiceImpl(TopicRepository repository) {
        super(repository);
        this.topicRepository = repository;
    }

    @Override
    public TopicDetailDto getById(String topicId) {
        Optional<Topic> topic = topicRepository.findById(topicId);

        TopicDetailDto result = topic.map(topicMapper::domainToDetailDto).orElseThrow(() -> new BusinessException("主题详情为空"));

        return result;
    }

    @Override
    public Topic getDomainById(String topicId) {
        Optional<Topic> optional = topicRepository.findById(topicId);
        if (optional.isPresent()) {
            return optional.get();
        }
        return null;
    }

    @Override
    public Page<Topic> findByParams(TopicQueryDto queryDto, Pageable pageable) {
        // 1、拼查询公共条件
        Query queryCriteria = createFindQuery(queryDto);

        // 2、在 queryCriteria基础上再拼每个查询特有的一些查询条件
        // 3、拼分页参数
        queryCriteria.with(pageable);

        // 4、拼排序参数
        queryCriteria.with(Sort.by(Sort.Order.desc("id")));

        // 5、查询记录条件
        long count = mongoTemplate.count(queryCriteria, Topic.class);
        List<Topic> content = new ArrayList<>();
        if (count > 0) {
            // 6、分页查询数据
            content = mongoTemplate.find(queryCriteria, Topic.class);
        }
        return PageableExecutionUtils.getPage(content, pageable, () -> count);
    }

    @Override
    public List<Topic> getIndexTopic(CityQueryDto queryDto) {
        Query query = new Query().addCriteria(Criteria.where("corporationCode").is(QfContextHolder.getContext().getCorporationCode()));
        query.addCriteria(Criteria.where("cityCode").is(queryDto.getCityCode()));
        query.addCriteria(Criteria.where("topicStatus").is("上架"));
        query.with(Sort.by(Sort.Order.asc("topicSort")));
        return mongoTemplate.find(query, Topic.class);
    }

    @Override
    public void saveTopic(Topic topic) {
        Date now = new Date();
        topic.setUpDownDate(now);
        if (StringUtils.isEmpty(topic.getId())) {
            topic.setCreateTime(now);
            topic.setId(ObjectId.get().toString());
            topicRepository.insert(topic);
        } else {
            topic.setUpdateTime(now);
            updateById(topic);
        }
    }

    private Query createFindQuery(TopicQueryDto queryDto) {
        Query query = new Query();
        Criteria criteria = Criteria.where("corporationCode").is(queryDto.getCorporationCode());
        if(StringUtils.isNotBlank(queryDto.getCityCode())){
            criteria.and("cityCode").is(queryDto.getCityCode());
        } else if (!CollectionUtils.isEmpty(queryDto.getCityCodes())){
            criteria.and("cityCode").in(queryDto.getCityCodes());
        }
        if(StringUtils.isNotEmpty(queryDto.getTopicType())) {
            criteria.and("topicType").is(queryDto.getTopicType());
        }
        if(StringUtils.isNotEmpty(queryDto.getTopicName())) {
            criteria.and("topicName").regex(".*?" + queryDto.getTopicName() + ".*");
        }
        query.addCriteria(criteria);
        return query;
    }
}
